/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#ifndef mozilla_image_FrameTimeout_h#define mozilla_image_FrameTimeout_h#include<stdint.h>#include"mozilla/Assertions.h"namespacemozilla{namespaceimage{/** * FrameTimeout wraps a frame timeout value (measured in milliseconds) after * first normalizing it. This normalization is necessary because some tools * generate incorrect frame timeout values which we nevertheless have to * support. For this reason, code that deals with frame timeouts should always * use a FrameTimeout value rather than the raw value from the image header. */structFrameTimeout{/** * @return a FrameTimeout of zero. This should be used only for math * involving FrameTimeout values. You can't obtain a zero FrameTimeout from * FromRawMilliseconds(). */staticFrameTimeoutZero(){returnFrameTimeout(0);}/// @return an infinite FrameTimeout.staticFrameTimeoutForever(){returnFrameTimeout(-1);}/// @return a FrameTimeout obtained by normalizing a raw timeout value.staticFrameTimeoutFromRawMilliseconds(int32_taRawMilliseconds){// Normalize all infinite timeouts to the same value.if(aRawMilliseconds<0){returnFrameTimeout::Forever();}// Very small timeout values are problematic for two reasons: we don't want// to burn energy redrawing animated images extremely fast, and broken tools// generate these values when they actually want a "default" value, so such// images won't play back right without normalization. For some context,// see bug 890743, bug 125137, bug 139677, and bug 207059. The historical// behavior of IE and Opera was:// IE 6/Win:// 10 - 50ms is normalized to 100ms.// >50ms is used unnormalized.// Opera 7 final/Win:// 10ms is normalized to 100ms.// >10ms is used unnormalized.if(aRawMilliseconds>=0&&aRawMilliseconds<=10){returnFrameTimeout(100);}// The provided timeout value is OK as-is.returnFrameTimeout(aRawMilliseconds);}booloperator==(constFrameTimeout&aOther)const{returnmTimeout==aOther.mTimeout;}booloperator!=(constFrameTimeout&aOther)const{return!(*this==aOther);}FrameTimeoutoperator+(constFrameTimeout&aOther){if(*this==Forever()||aOther==Forever()){returnForever();}returnFrameTimeout(mTimeout+aOther.mTimeout);}FrameTimeout&operator+=(constFrameTimeout&aOther){*this=*this+aOther;return*this;}/** * @return this FrameTimeout's value in milliseconds. Illegal to call on a * an infinite FrameTimeout value. */uint32_tAsMilliseconds()const{if(*this==Forever()){MOZ_ASSERT_UNREACHABLE("Calling AsMilliseconds() on an infinite FrameTimeout");return100;// Fail to something sane.}returnuint32_t(mTimeout);}/** * @return this FrameTimeout value encoded so that non-negative values * represent a timeout in milliseconds, and -1 represents an infinite * timeout. * * XXX(seth): This is a backwards compatibility hack that should be removed. */int32_tAsEncodedValueDeprecated()const{returnmTimeout;}private:explicitFrameTimeout(int32_taTimeout):mTimeout(aTimeout){}int32_tmTimeout;};}// namespace image}// namespace mozilla#endif // mozilla_image_FrameTimeout_h